﻿using SimpleLogger;
using System;
using System.Collections.Concurrent;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using DotNet.Utilities;

namespace WPFTemplateLib.UserControls
{
    /// <summary>
    /// 信息区 用户控件
    /// </summary>
    public partial class UC_InfoRegion : UserControl
    {
        public UC_InfoRegion()
        {
            InitializeComponent();

            Task.Factory.StartNew(() =>
            {
                foreach (string info in _BC.GetConsumingEnumerable())
                {
                    try
                    {
                        Dispatcher.Invoke(() =>
                        {
                            //TBInfo.Text += info;
                            ShowInfo(info);
                        });
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"{ex}");
                    }
                }
            }, TaskCreationOptions.LongRunning);
        }

        #region 成员

        /// <summary>
        /// 阻塞集合;
        /// </summary>
        private readonly BlockingCollection<string> _BC = new BlockingCollection<string>();

        #endregion

        #region 依赖属性

        #region 是否自动滚动

        public bool IsAutoScroll
        {
            get { return (bool)GetValue(IsAutoScrollProperty); }
            set { SetValue(IsAutoScrollProperty, value); }
        }

        public static readonly DependencyProperty IsAutoScrollProperty =
            DependencyProperty.Register("IsAutoScroll", typeof(bool), typeof(UC_InfoRegion), new PropertyMetadata(true));

        #endregion

        #region 是否记录到日志

        public bool IsRecordToLog
        {
            get { return (bool)GetValue(IsRecordToLogProperty); }
            set { SetValue(IsRecordToLogProperty, value); }
        }

        public static readonly DependencyProperty IsRecordToLogProperty =
            DependencyProperty.Register("IsRecordToLog", typeof(bool), typeof(UC_InfoRegion), new PropertyMetadata(false));

        #endregion

        #region 是否自动消息减半

        public bool IsAutoHalve
        {
            get { return (bool)GetValue(IsAutoHalveProperty); }
            set { SetValue(IsAutoHalveProperty, value); }
        }

        public static readonly DependencyProperty IsAutoHalveProperty =
            DependencyProperty.Register("IsAutoHalve", typeof(bool), typeof(UC_InfoRegion), new PropertyMetadata(true));

        #endregion

        #region 消息减半行数阈值

        /// <summary>
        /// 消息减半行数阈值
        /// </summary>
        public int AutoHalveLineThreshold
        {
            get { return (int)GetValue(AutoHalveLineThresholdProperty); }
            set { SetValue(AutoHalveLineThresholdProperty, value); }
        }

        public static readonly DependencyProperty AutoHalveLineThresholdProperty =
            DependencyProperty.Register("AutoHalveLineThreshold", typeof(int), typeof(UC_InfoRegion), new PropertyMetadata(10000));

        #endregion

        #region 当前要显示的文本

        public string InfoText
        {
            get { return (string)GetValue(InfoTextProperty); }
            set { SetValue(InfoTextProperty, value); }
        }

        public static readonly DependencyProperty InfoTextProperty =
            DependencyProperty.Register("InfoText", typeof(string), typeof(UC_InfoRegion),
                new PropertyMetadata(null, InfoTextChangedCallback));

        private static void InfoTextChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //new Thread(() =>
            //{
            //    var that = (UC_InfoRegion)d;
            //    if (e.NewValue != null)
            //    {
            //        //that.ShowInfo(e.NewValue+"");
            //        that._BC.Add(e.NewValue + "");
            //    }
            //}).Start();
        }

        #endregion

        #endregion

        #region 辅助方法

        private void ShowInfo(string info, [CallerFilePath] string filePath = "", [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0)
        {
            var lines = TBInfo.Text.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList();
            if (lines.Count > AutoHalveLineThreshold && IsAutoHalve)
            {
                int removeLines = lines.Count - Math.Abs(AutoHalveLineThreshold) / 2;
                lines.RemoveRange(0, removeLines);
                TBInfo.Text = $"(已删除[{removeLines}]行信息){Environment.NewLine.Repeat(2)}" + string.Join(Environment.NewLine, lines);
            }

            TBInfo.Text += $"[{DateTime.Now:HH:mm:ss.ffff}] {info}{Environment.NewLine}";
            //_BC.Add($"[{DateTime.Now:HH:mm:ss.ffff}] {info}{Environment.NewLine}");

            if (IsRecordToLog)
            {
                LogHelper.Write(info, true, filePath, memberName, lineNumber);
            }
        }

        public void AddInfo(string info)
        {
            if (info != null)
            {
                _BC.Add(info);
            }
        }

        #endregion

        #region 事件方法

        private void BtnClear_OnClick(object sender, RoutedEventArgs e)
        {
            TBInfo.Clear();
        }

        #endregion
    }

    public class InfoRegionConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var uc = values[0] as UC_InfoRegion;
            uc.AddInfo(values[1] + "");
            return null;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
